package http

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"io/ioutil"
	"mall-portalv2/conf"
	"mall-portalv2/global"
	"mall-portalv2/internal/model"
	"mall-portalv2/internal/server/ctx"
	utils_jwt "mall-portalv2/library/utils.jwt"
	"net/http"
	"strings"
	"time"
)

const (
	defaultNickName = "用户"
	defaultIcon     = "https://cdn.iotdreamcatcher.net.cn/assets/20230222-165335.png"
)

func SsoJiaChaoUserLogin(c *gin.Context) {
	app := ctx.Gin{C: c}

	tokentemp := c.Request.Header.Get("token")

	global.Log.Info("打印一下token", zap.Any("token", tokentemp))

	if tokentemp == "" || len(tokentemp) <= 7 {
		global.Log.Error("收到的token为空")
		app.Response(http.StatusBadRequest, ctx.StatusBadRequest, nil)
		return
	}

	//{
	//	"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDIzNTQzMzIsInVpZCI6MjUzMDg1LCJ6b25lIjoiVFMifQ.qJWEgc3TQsjMEOxbpCcFB3AyX3kb25-oN2YfxLkGpVI",
	//	"sign":"4EFA6ABE8BDE060AEE18F82228E90E45",
	//	"timestamp": 1674885781
	//}

	type SendBody struct {
		Token     string `json:"token" validate:"required"`
		Sign      string `json:"sign" validate:"required"`
		Timestamp int64  `json:"timestamp" validate:"required"`
	}

	nowTime := time.Now().Unix()

	send := SendBody{
		Token:     tokentemp,
		Sign:      utils_jwt.CreateSign(tokentemp, fmt.Sprintf("%d", nowTime), conf.Config.Jiachao.AuthKey),
		Timestamp: nowTime,
	}

	global.Log.Info("打印请求前参数", zap.Any("send", send))

	fn := clientPost(conf.Config.Jiachao.AuthApi, send)

	result, err := fn()
	if err != nil {
		global.Log.Error("请求家超用户中间件出错", zap.Error(err))
		app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
		return
	}

	type SendResult struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
		Result  struct {
			Phone   string `json:"phone"`
			Email   string `json:"email"`
			UserId  int64  `json:"user_id"`
			UserKey string `json:"user_key"`
			Alias   string `json:"alias"`
			PictUrl string `json:"pict_url"`
		} `json:"result"`
	}

	sendResult := SendResult{}
	json.Unmarshal(result, &sendResult)

	//global.Log.Info("打印结果", zap.Any("sendResult", sendResult))

	if sendResult.Code == 1 {
		// TODO: 存key到redis
		if err := svc.RedisServiceSet(context.Background(), tokentemp, sendResult.Result.UserKey, time.Hour*24); err != nil {
			global.Log.Error("redis存储出了点错误", zap.Error(err))
			app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
			return
		}

		// TODO: 录入众筹体系
		queryMemberResult, err := svc.QueryUmsMemberWhereID(c, sendResult.Result.UserId)
		if err != nil {
			if err != gorm.ErrRecordNotFound {
				global.Log.Error("查询出了错误", zap.Error(err))
				app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
				return
			}
		}

		//global.Log.Info("打印结果", zap.Any("queryMemberResult", queryMemberResult))

		if queryMemberResult.ID > 0 {
			// TODO: 更新头像等信息
			updates := make(map[string]interface{})
			updates["phone"] = sendResult.Result.Phone
			updates["email"] = sendResult.Result.Email
			finishNickName := ""
			finishIcon := ""
			if sendResult.Result.Alias == "" || len(sendResult.Result.Alias) <= 0 {
				finishNickName = fmt.Sprintf("%s%d", defaultNickName, sendResult.Result.UserId)
			} else {
				finishNickName = sendResult.Result.Alias
			}
			if sendResult.Result.PictUrl == "" || len(sendResult.Result.PictUrl) <= 0 {
				finishIcon = defaultIcon
			} else {
				finishIcon = sendResult.Result.PictUrl
			}
			updates["nickname"] = finishNickName
			updates["icon"] = finishIcon
			updates["password"] = sendResult.Result.UserKey
			if err := svc.UpdateUmsMember(c, sendResult.Result.UserId, updates); err != nil {
				global.Log.Error("更新出了错误", zap.Error(err))
				app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
				return
			}
		} else {
			// TODO: 注册新用户
			queryMemberDefaultLevel, err := svc.QueryDefaultUmsMemberLevel(c)
			if err != nil {
				global.Log.Error("查询出了错误", zap.Error(err))
				app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
				return
			}
			//global.Log.Info("打印结果", zap.Any("queryMemberDefaultLevel", queryMemberDefaultLevel.ID))

			tempUserName := ""
			if sendResult.Result.Phone != "" && len(sendResult.Result.Phone) > 0 {
				tempUserName = sendResult.Result.Phone
			} else if sendResult.Result.Email != "" && len(sendResult.Result.Email) > 0 {
				tempUserName = sendResult.Result.Email
			} else {
				tempUserName = "user_" + uuid.NewString()
			}

			now := time.Now()
			finishNickName := ""
			finishIcon := ""
			if sendResult.Result.Alias == "" || len(sendResult.Result.Alias) <= 0 {
				finishNickName = fmt.Sprintf("%s%d", defaultNickName, sendResult.Result.UserId)
			} else {
				finishNickName = sendResult.Result.Alias
			}
			if sendResult.Result.PictUrl == "" || len(sendResult.Result.PictUrl) <= 0 {
				finishIcon = defaultIcon
			} else {
				finishIcon = sendResult.Result.PictUrl
			}

			insertModel := model.UmsMember{
				ID:            sendResult.Result.UserId,
				Username:      tempUserName,
				Phone:         sendResult.Result.Phone,
				Nickname:      finishNickName,
				Icon:          finishIcon,
				Password:      sendResult.Result.UserKey,
				CreateTime:    &now,
				Status:        1,
				MemberLevelId: queryMemberDefaultLevel.ID,
			}
			createMemberResult, err := svc.CreateUmsMember(c, insertModel)
			if err != nil {
				global.Log.Error("创建用户出了错误", zap.Error(err))
				app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, err)
				return
			}
			global.Log.Info("打印结果", zap.Any("createMemberResult", createMemberResult))
		}

		app.Response(http.StatusOK, ctx.StatusOK, nil)
		return
	} else {
		global.Log.Error("请求家超用户体系错误", zap.Any("err", sendResult))
		app.Response(http.StatusInternalServerError, ctx.StatusInternalServerError, sendResult)
		return
	}

	app.Response(http.StatusOK, ctx.OK, nil)
}

var (
	client *http.Client
)

func init() {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client = &http.Client{Transport: tr}
}

func clientPost(url string, in interface{}) func() ([]byte, error) {
	var body []byte
	var err error

	c := make(chan struct{}, 1)
	go func() {
		defer close(c)

		var res *http.Response
		jsonBody, _ := json.Marshal(in)
		res, err = client.Post(url, "application/json", strings.NewReader(string(jsonBody)))

		if err != nil {
			return
		}

		defer res.Body.Close()
		body, err = ioutil.ReadAll(res.Body)
		return
	}()
	return func() ([]byte, error) {
		i, ok := <-c
		fmt.Println(ok)
		if !ok {
			fmt.Println("channel closed!")
			return body, err
		}
		fmt.Println(i)
		return body, err
	}
}
